﻿#include "TcpClient.h"
#include <QHostAddress>
#include <QNetworkProxy>

using namespace FCMiddleware;

TcpClient::TcpClient(QObject *parent)
	: QObject(parent)
{
	_tcpClient = NULL;
}

TcpClient::TcpClient(const QString& hostName, unsigned short hostPort, QObject *parent)
	: QObject(parent)
{
	_hostName = hostName;
	_hostPort = hostPort;

	_tcpClient = NULL;
}


TcpClient::~TcpClient()
{
}

bool TcpClient::connectToServer(unsigned int overtime, int* err)
{
	_tcpClient = new QTcpSocket();
	_tcpClient->setProxy(QNetworkProxy::NoProxy);
	_tcpClient->setReadBufferSize(65536);

	const QHostAddress address = QHostAddress(_hostName);
	_tcpClient->connectToHost(address, _hostPort);

	if (_tcpClient->waitForConnected(overtime * 1000))
	{
		_tcpClient->setSocketOption(QAbstractSocket::LowDelayOption, 1);
		_tcpClient->setSocketOption(QAbstractSocket::SendBufferSizeSocketOption, 65536);
		_tcpClient->setSocketOption(QAbstractSocket::ReceiveBufferSizeSocketOption, 65536);
		return true;
	}
	else
	{
		*err = _tcpClient->error();
		qDebug() << _tcpClient->errorString();
		return false;
	}
}

int TcpClient::recv(unsigned char* recvBuf, unsigned int size, int* err)
{
	Q_ASSERT(_tcpClient != NULL);

	if (!_tcpClient->waitForReadyRead(5))
	{
		*err = _tcpClient->error();
		if (*err != QAbstractSocket::SocketTimeoutError)
		{
			qDebug() << _tcpClient->errorString();
			return -1;
		}
		else return 0;
	}
		
	qint64 ret = _tcpClient->bytesAvailable();
	if (ret == 0)
		return 0;

	if (ret < size)
		size = ret;

	ret = _tcpClient->read((char*)recvBuf, size);
	if (ret == -1)
	{
		*err = _tcpClient->error();
		qDebug() << _tcpClient->errorString();
		return -1;
	}
	else return ret;
}

int TcpClient::send(char* sendBuf, unsigned int size, int* err)
{
	Q_ASSERT(_tcpClient != NULL);

	int ret = _tcpClient->write(sendBuf, size);
	if (ret == -1)
	{
		*err = _tcpClient->error();
		qDebug() << _tcpClient->errorString();

		return -1;
	}

	if (!_tcpClient->waitForBytesWritten(5))
	{
		*err = _tcpClient->error();
		if (*err != QAbstractSocket::SocketTimeoutError)
		{
			qDebug() << _tcpClient->errorString();
			return -1;
		}
		else return 0;
	}
	else return 0;
}

void TcpClient::destory()
{
	if (_tcpClient == NULL)
		return;

	if (_tcpClient->state() == QAbstractSocket::ConnectedState)
		_tcpClient->disconnectFromHost();

	delete _tcpClient;
	_tcpClient = NULL;
}
